CREATE OR REPLACE FUNCTION soporte.ctb_renumeracion_asientos(
	character varying,
	character varying, 
	integer)
    RETURNS character varying
    LANGUAGE 'plpgsql'
    COST 100
AS $BODY$
DECLARE
pCodAmbEmp	 		ALIAS FOR $1;
pCodCtbEje 			ALIAS FOR $2;
pNroAsiIni			ALIAS FOR $3;

vCantAsiModificados	integer;
BEGIN

-- Renumera los asientos de Libro Diario para una empresa y un ejercicio contable.
-- Solo toma las sucursales fiscales.

-- Para probar:      select soporte.ctb_renumeracion_asientos('a1', 'C', 1)

-- Creamos una tabla auxiliar.

CREATE TABLE soporte.ctb_asientos_renumerados(
	idcomm					integer,
	fecharesumen			text,
	codctbsub				text,
	codambsuc_resumen		text,
	mi_nro_asi				integer
)
WITH (OIDS=TRUE);
ALTER TABLE soporte.ctb_asientos_renumerados OWNER TO abacouser;
COMMENT ON TABLE soporte.ctb_asientos_renumerados IS 'Tabla auxiliar, la usa la funcion pg: soporte.ctb_renumeracion_asientos(...)';

-- GRAN QUERY...

WITH qSuc AS 
(
select servicios_fiscales.get_sucursales_fiscales(pCodAmbEmp, '') as Sys_UniSucFis
), 

qCtbEje AS
(
select fechaini, fechafin
from ctbeje
where codambemp = pCodAmbEmp and cod = pCodCtbEje
),

qComm AS
(
SELECT comm.id AS idcomm, comm.fecharesumen, comm.codctbsub, comm.codambsuc, COALESCE(comm.nroasi, 0) AS nroasi,

	CASE WHEN comm.tipocom = ctbcfg.asientoaperturatipocom OR comm.generadopor = 'Apertura' THEN 10
		 WHEN comm.tipocom = ctbcfg.asientocierretipocom OR comm.generadopor = 'Cierre' THEN 90
		 WHEN comm.tipocom = ctbcfg.reitipocom OR comm.generadopor = 'REI' THEN 80
		 WHEN comm.codctbsub <> 'DI' THEN 70
	ELSE 50 END AS orden_asi, 

	CASE WHEN comm.codctbsub = 'DI' OR ctbcfg.ressubdiarioxsuc = 'S' THEN comm.codambsuc ELSE 'TODAS' END AS codambsuc_resumen, 
	CASE WHEN comm.codctbsub = 'DI' THEN comm.id ELSE NULL END AS idcomm_resumen
	
FROM comm
JOIN ctbcfg ON true
JOIN qCtbEje ON true
WHERE comm.escontable = 'S' AND
	  position(comm.codambsuc in (select Sys_UniSucFis from qSuc)) > 0 AND
	  EXISTS(select * from commov where comm.id = commov.idcomm) AND
      comm.fecha BETWEEN qCtbEje.fechaini AND qCtbEje.fechafin
),

qGrupos AS
(
SELECT qComm.idcomm_resumen, qComm.fecharesumen, qComm.codctbsub, qComm.codambsuc_resumen
FROM qComm
GROUP BY 1,2,3,4
), 

qGrupos_rank AS
(
SELECT qGrupos.fecharesumen, qGrupos.codctbsub, qGrupos.codambsuc_resumen, qGrupos.idcomm_resumen, 
       pNroAsiIni - 1 + row_number() OVER (ORDER BY qGrupos.fecharesumen, qGrupos.codctbsub, qGrupos.codambsuc_resumen) AS mi_nro_asi
FROM qGrupos
),

qFinal AS
(
SELECT qComm.idcomm, qComm.fecharesumen, qComm.codctbsub, qComm.codambsuc_resumen, 
	COALESCE(qRank1.mi_nro_asi, qRank2.mi_nro_asi) AS mi_nro_asi
FROM qComm
LEFT JOIN qGrupos_rank qRank1 ON qComm.idcomm = qRank1.idcomm_resumen
LEFT JOIN qGrupos_rank qRank2 ON qRank2.idcomm_resumen IS NULL AND
	qComm.fecharesumen = qRank2.fecharesumen AND
	qComm.codctbsub = qRank2.codctbsub AND
	qComm.codambsuc_resumen = qRank2.codambsuc_resumen
WHERE qComm.nroasi <> COALESCE(qRank1.mi_nro_asi, qRank2.mi_nro_asi)
ORDER BY qComm.fecharesumen, qComm.codctbsub, qComm.codambsuc_resumen, qComm.idcomm
)

-- Insertamos en la tabla auxiliar los comprobantes que renumeraremos para luego poder contarlos y devolver la cant. como resultado de la función.
INSERT INTO soporte.ctb_asientos_renumerados(idcomm, fecharesumen, codctbsub, codambsuc_resumen, mi_nro_asi)
SELECT idcomm, fecharesumen, codctbsub, codambsuc_resumen, mi_nro_asi
FROM qFinal
ORDER BY fecharesumen, codctbsub, codambsuc_resumen, idcomm;

-- BAJAMOS ALGUNOS TRIGGERS de update.
-- En especial el de fechaupdate para que no le ponga a todos la misma y perdemos trazabilidad anterior con el comm.
-- Creo que no hay riesgo trabajando en paralelo con otros comprobantes, porque el resto verá el cambio después que se ejecute toda esta transacción (Edu)

DROP TRIGGER check_rango_numeros_comm ON public.comm;
DROP TRIGGER check_turno_no_cerrado_comm ON public.comm;
DROP TRIGGER control_audit_comm ON public.comm;
DROP TRIGGER comm_010_ins_upd_descxlike ON public.comm;
DROP TRIGGER comm_commov ON public.comm;
DROP TRIGGER comm_ins_up_controlfechas ON public.comm;
DROP TRIGGER insert_update_comm ON public.comm;

-- ACTUALIZAMOS el número de asiento de cada comm solo para los que cambiaron.
UPDATE comm SET nroasi = qFinal.mi_nro_asi
FROM soporte.ctb_asientos_renumerados qFinal
WHERE comm.id = qFinal.idcomm;

-- SUBIMOS LOS TRIGGERS.

CREATE TRIGGER check_rango_numeros_comm
    BEFORE INSERT OR UPDATE 
    ON public.comm
    FOR EACH ROW
    EXECUTE FUNCTION public.tg_comm_ins_upd_controlrangonumeros();

CREATE TRIGGER check_turno_no_cerrado_comm
    BEFORE INSERT OR DELETE OR UPDATE 
    ON public.comm
    FOR EACH ROW
    EXECUTE FUNCTION public.tg_check_turno_no_cerrado();

CREATE TRIGGER control_audit_comm
    BEFORE INSERT OR DELETE OR UPDATE 
    ON public.comm
    FOR EACH ROW
    EXECUTE FUNCTION public.tg_control_audit_instancia();

CREATE TRIGGER comm_010_ins_upd_descxlike
    BEFORE INSERT OR UPDATE 
    ON public.comm
    FOR EACH ROW
    EXECUTE FUNCTION public.tg_comm_ins_upd_descxlike();

CREATE TRIGGER comm_commov
    AFTER UPDATE 
    ON public.comm
    FOR EACH ROW
    EXECUTE FUNCTION public.tg_comm_commov();

CREATE TRIGGER comm_ins_up_controlfechas
    BEFORE INSERT OR UPDATE 
    ON public.comm
    FOR EACH ROW
    EXECUTE FUNCTION public.tg_comm_ins_upd_controlfechas();

CREATE TRIGGER insert_update_comm
    BEFORE INSERT OR UPDATE 
    ON public.comm
    FOR EACH ROW
    EXECUTE FUNCTION public.tg_insert_update_comm();

vCantAsiModificados:= (select count(*) from soporte.ctb_asientos_renumerados);

RETURN 'Se renumeraron ' || vCantAsiModificados || ' comprobantes';

END
$BODY$;

ALTER FUNCTION soporte.ctb_renumeracion_asientos(character varying, character varying, integer) OWNER TO abacouser;

-- ==================================
SELECT aaversion('476.01', '476.00');
-- ==================================

